package com.example.demo.service;

import com.example.demo.dto.ChatRequest;
import com.example.demo.dto.ChatResponse;
import com.example.demo.dto.RecipeResponse;
import com.theokanning.openai.completion.chat.ChatCompletionRequest;
import com.theokanning.openai.completion.chat.ChatCompletionResult;
import com.theokanning.openai.completion.chat.ChatMessage;
import com.theokanning.openai.completion.chat.ChatMessageRole;
import com.theokanning.openai.service.OpenAiService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * AI聊天服务类
 * 负责与DeepSeek AI进行交互，提供不同类型的聊天功能
 * 
 * @author AI Demo
 * @version 1.0
 */
@Service
@RequiredArgsConstructor
public class ChatService {

    /** DeepSeek AI服务实例 */
    private final OpenAiService openAiService;

    /**
     * 基础聊天功能
     * 发送用户消息给AI并获取回复
     * 
     * @param userMessage 用户输入的消息
     * @return AI的回复内容，如果出错则返回错误信息
     */
    public String chat(String userMessage) {
        try {
            // 创建用户消息对象
            ChatMessage message = new ChatMessage(ChatMessageRole.USER.value(), userMessage);
            
            // 构建聊天完成请求
            ChatCompletionRequest request = ChatCompletionRequest.builder()
                    .model("deepseek-chat")           // 使用DeepSeek聊天模型
                    .messages(Arrays.asList(message))  // 设置消息列表
                    .temperature(0.7)                  // 设置创造性参数(0-1)
                    .maxTokens(1000)                   // 设置最大回复长度
                    .build();
            
            // 调用AI服务获取回复
            ChatCompletionResult result = openAiService.createChatCompletion(request);
            return result.getChoices().get(0).getMessage().getContent();
        } catch (Exception e) {
            // 异常处理，返回友好的错误信息
            return "对话失败: " + e.getMessage();
        }
    }

    /**
     * 带系统消息的聊天功能
     * 通过系统消息设定AI的角色和行为模式，然后进行对话
     * 
     * @param userMessage 用户输入的消息
     * @param systemMessage 系统消息，用于设定AI的角色和行为
     * @return AI的回复内容，如果出错则返回错误信息
     */
    public String chatWithSystem(String userMessage, String systemMessage) {
        try {
            // 创建消息列表，包含系统消息和用户消息
            List<ChatMessage> messages = Arrays.asList(
                    new ChatMessage(ChatMessageRole.SYSTEM.value(), systemMessage), // 系统角色设定
                    new ChatMessage(ChatMessageRole.USER.value(), userMessage)      // 用户消息
            );
            
            // 构建聊天完成请求
            ChatCompletionRequest request = ChatCompletionRequest.builder()
                    .model("deepseek-chat")           // 使用DeepSeek聊天模型
                    .messages(messages)                // 设置包含系统消息的消息列表
                    .temperature(0.7)                  // 设置创造性参数
                    .maxTokens(1000)                   // 设置最大回复长度
                    .build();
            
            // 调用AI服务获取回复
            ChatCompletionResult result = openAiService.createChatCompletion(request);
            return result.getChoices().get(0).getMessage().getContent();
        } catch (Exception e) {
            // 异常处理，返回友好的错误信息
            return "对话失败: " + e.getMessage();
        }
    }

    /**
     * 处理聊天请求并返回AI回复
     * 
     * @param request 聊天请求对象，包含用户消息和可选的系统消息
     * @return 包含用户消息和AI回复的完整对话响应
     */
    public ChatResponse chat(ChatRequest request) {
        // 构建系统消息，如果请求中没有指定则使用默认消息
        String systemMessage = (request.getSystem() != null && !request.getSystem().trim().isEmpty()) ? 
                request.getSystem() : "你是一个有用的AI助手，请友好地回答用户的问题。";
        
        // 创建消息列表，包含系统消息和用户消息
        List<ChatMessage> messages = Arrays.asList(
                new ChatMessage(ChatMessageRole.SYSTEM.value(), systemMessage),
                new ChatMessage(ChatMessageRole.USER.value(), request.getMessage())
        );
        
        // 构建聊天完成请求
        ChatCompletionRequest chatRequest = ChatCompletionRequest.builder()
                .model("deepseek-chat")  // 使用DeepSeek聊天模型
                .messages(messages)
                .maxTokens(1000)  // 限制回复长度
                .temperature(0.7)  // 设置创造性参数
                .build();
        
        // 调用OpenAI服务获取回复
        ChatCompletionResult result = openAiService.createChatCompletion(chatRequest);
        String assistantReply = result.getChoices().get(0).getMessage().getContent();
        
        // 返回包含完整对话信息的响应
        return new ChatResponse(request.getMessage(), assistantReply, systemMessage, System.currentTimeMillis());
    }
    
    /**
     * 查询菜品制作信息
     * 使用固定的美食专家角色，根据菜品名称获取制作配料和制作方法
     * 
     * @param dishName 菜品名称
     * @return 包含制作配料和制作方法的菜品信息响应
     */
    public RecipeResponse getRecipe(String dishName) {
        // 固定的美食专家系统角色
        String systemMessage = "你是一个美食专家，当发送一个菜品名称给你后，你需要返回该菜品的制作配料以及制作方法。请按照以下格式回复：\n\n制作配料：\n1. 配料1\n2. 配料2\n...\n\n制作方法：\n1. 步骤1\n2. 步骤2\n...";
        
        // 创建消息列表
        List<ChatMessage> messages = Arrays.asList(
                new ChatMessage(ChatMessageRole.SYSTEM.value(), systemMessage),
                new ChatMessage(ChatMessageRole.USER.value(), dishName)
        );
        
        // 构建聊天完成请求
        ChatCompletionRequest chatRequest = ChatCompletionRequest.builder()
                .model("deepseek-chat")
                .messages(messages)
                .maxTokens(1500)  // 增加token限制以获取完整的制作信息
                .temperature(0.3)  // 降低创造性，提高准确性
                .build();
        
        // 调用OpenAI服务获取回复
        ChatCompletionResult result = openAiService.createChatCompletion(chatRequest);
        String assistantReply = result.getChoices().get(0).getMessage().getContent();
        
        // 解析AI回复，提取配料和制作方法
        List<String> ingredients = extractIngredients(assistantReply);
        List<String> methods = extractMethods(assistantReply);
        
        // 后台打印提取到的数组信息
        System.out.println("=== 菜品制作信息提取结果 ===");
        System.out.println("菜品名称: " + dishName);
        System.out.println("配料数组: " + ingredients);
        System.out.println("制作方法数组: " + methods);
        System.out.println("==============================");
        
        // 返回结构化的菜品制作信息
        return new RecipeResponse(dishName, ingredients, methods, assistantReply);
    }
    
    /**
     * 从AI回复中提取制作配料
     * 
     * @param response AI的原始回复
     * @return 配料列表
     */
    private List<String> extractIngredients(String response) {
        List<String> ingredients = new ArrayList<>();
        
        // 使用正则表达式匹配配料部分
        Pattern pattern = Pattern.compile("制作配料[：:](.*?)(?=制作方法|$)", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(response);
        
        if (matcher.find()) {
            String ingredientsSection = matcher.group(1).trim();
            // 按行分割并提取每个配料
            String[] lines = ingredientsSection.split("\\n");
            for (String line : lines) {
                line = line.trim();
                if (!line.isEmpty()) {
                    // 移除序号、Markdown符号和特殊字符，只保留配料名称
                    String ingredient = line.replaceAll("^\\d+[.、]\\s*", "")
                            .replaceAll("\\*\\*", "")  // 移除粗体标记
                            .replaceAll("\\*", "")    // 移除斜体标记
                            .replaceAll("^-\\s*", "")  // 移除列表标记
                            .replaceAll("^•\\s*", "")  // 移除圆点标记
                            .trim();
                    if (!ingredient.isEmpty()) {
                        ingredients.add(ingredient);
                    }
                }
            }
        }
        
        return ingredients;
    }
    
    /**
     * 从AI回复中提取制作方法
     * 
     * @param response AI的原始回复
     * @return 制作方法步骤列表
     */
    private List<String> extractMethods(String response) {
        List<String> methods = new ArrayList<>();
        
        // 使用正则表达式匹配制作方法部分
        Pattern pattern = Pattern.compile("制作方法[：:](.*?)$", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(response);
        
        if (matcher.find()) {
            String methodsSection = matcher.group(1).trim();
            // 按行分割并提取每个步骤
            String[] lines = methodsSection.split("\\n");
            for (String line : lines) {
                line = line.trim();
                if (!line.isEmpty()) {
                    // 移除序号、Markdown符号和特殊字符，只保留步骤内容
                    String method = line.replaceAll("^\\d+[.、]\\s*", "")
                            .replaceAll("\\*\\*", "")  // 移除粗体标记
                            .replaceAll("\\*", "")    // 移除斜体标记
                            .replaceAll("^-\\s*", "")  // 移除列表标记
                            .replaceAll("^•\\s*", "")  // 移除圆点标记
                            .trim();
                    if (!method.isEmpty()) {
                        methods.add(method);
                    }
                }
            }
        }
        
        return methods;
    }
}
